using System;
using System.Collections.Generic;
using System.Text;
using ACS.Compiler.Tables.Modes;
using ACS.Compiler.Tree.Impl;
using ACS.Compiler.Util;

namespace ACS.Compiler.Tables
{
    public class ProcTable
    {
        private static ProcTable _instance;
        public static ProcTable Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new ProcTable();
                }
                return _instance;
            }
        }

        public ProcTable()
        {
            List<DataField> list = new List<DataField>();
            list.Add(new DataField(null,null,IntMode.Instance));
            Procedure i2s = new Procedure("i2s", null, null, list, StringMode.Instance, null, true);
            Table.Add("i2s",i2s);

            List<DataField> list1 = new List<DataField>();
            list1.Add(new DataField(null,null,StringMode.Instance));
            Procedure s2i = new Procedure("s2i", null, null, list1, IntMode.Instance, null, true);
            Table.Add("s2i",s2i);

            List<DataField> list2 = new List<DataField>();
            list2.Add(new DataField(null,null,BottomMode.Instance));
            Procedure trace = new Procedure("trace", null, null, list2, null, null, true);
            Table.Add("trace", trace);
        }

        private Dictionary<string, Procedure> _table = new Dictionary<string, Procedure>();

        public Dictionary<string, Procedure> Table
        {
            get { return _table; }
        }

        public void AddProc(Procedure proc)
        {
            string key = proc.Namespace + "."  + proc.Name;
            if (_table.ContainsKey(key))
            {
                Logger.Instance.TraceError("procedure with this name is already declared.");
            } else
            {
                _table.Add(key, proc);  
            }
        }

        public Procedure FindProc(string ns, string name)
        {
            string key = ns + "." + name;
            Procedure proc;
            _table.TryGetValue(key, out proc);
            if (proc != null)
            {
                return proc;
            } else
            {
                //standart ones.
                _table.TryGetValue(name, out proc);
                return proc;
            }
        } 
    }
}
